package com.rfsp.common.schedule;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledFuture;

/**
 * @author crush
 */
@Component
public class DynamicTaskService {

    static final Logger log = LoggerFactory.getLogger(DynamicTaskService.class);
    /**
     * 以下两个都是线程安全的集合类。
     */
    Map<String, ScheduledFuture<?>> scheduledMap = new ConcurrentHashMap<>();
    List<String> scheduledList = new CopyOnWriteArrayList<>();

    @Resource
    ThreadPoolTaskScheduler scheduledPool;

    /**
     * 添加一个动态任务（一次性）
     *
     * @param startTime
     */
    public boolean start(Runnable runnable, Date startTime, String id) {
        // 此处的逻辑是 ，如果当前已经有这个名字的任务存在，先删除之前的，再添加现在的。（即重复就覆盖）
        if (null != scheduledMap.get(id)) {
            stop(id);
        }

        // schedule :调度给定的Runnable ，在指定的执行时间调用它。
        //一旦调度程序关闭或返回的ScheduledFuture被取消，执行将结束。
        //参数：
        //任务 – 触发器触发时执行的 Runnable
        //startTime – 任务所需的执行时间（如果这是过去，则任务将立即执行，即尽快执行）
        ScheduledFuture<?> schedule = scheduledPool.schedule(runnable, startTime);
        scheduledMap.put(id, schedule);
        scheduledList.add(id);
        return true;
    }

    /**
     * 停止任务（一次性）
     *
     * @param id
     */
    public boolean stop(String id) {
        if (null == scheduledMap.get(id)) {
            return false;
        }
        ScheduledFuture<?> scheduledFuture = scheduledMap.get(id);
        scheduledFuture.cancel(true);
        scheduledMap.remove(id);
        scheduledList.remove(id);
        return true;
    }


    /**
     * 添加一个cron任务
     */
    public void add(Runnable runnable, String cron, String id) {
        ScheduledFuture<?> sf = scheduledPool.schedule(runnable, (TriggerContext triggerContext) -> {
            Date nextExecutionTime = null;
            try {
                CronTrigger trigger = new CronTrigger(cron);
                nextExecutionTime = trigger.nextExecutionTime(triggerContext);
            } catch (Exception e) {
                log.info(e.getMessage());
            }
            return nextExecutionTime;
        });
        scheduledMap.put(id, sf);
        scheduledList.add(id);
        log.info("----------add scheduler finish-----------{}", id);
    }

    /**
     * 删除一个cron任务
     */
    public boolean remove(String id) {
        ScheduledFuture<?> sf = scheduledMap.get(id);

        sf.cancel(true);
        scheduledMap.remove(id);
        scheduledList.remove(id);

        log.info("----------delete scheduler finish-----------{}", id);
        return true;
    }






    /**
     * 运行任务
     *
     */
    public Runnable getTestTask() {
        return () -> {
            log.info("---动态定时任务运行---");
            try {
                System.out.println("此时时间==>" + LocalDateTime.now());
                System.out.println("task中设定的时间==>");
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("---end--------");
        };
    }


    /**
     * 查看已开启但还未执行的动态任务
     */
    public List<String> getTaskList() {
        return scheduledList;
    }

}